package com.leiy.job.task;

import com.leiy.job.Pojo.JobInfo;
import com.leiy.job.service.JobInfoService;
import com.leiy.job.utils.MathSalary;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.JsonPathSelector;

import java.text.MessageFormat;
import java.util.List;

@Component
@Slf4j
public class JobProcessor implements PageProcessor {

    @Autowired
    private SpringDataPipeline springDataPipeline;

    // 分页的第一页，注意处理占位符{0}
    private String url = "https://search.51job.com/list/040000,000000,0000,32%252c01,9,99,java,2,{0}.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=";
    // config 总页数
    private static final int PAGESIZE = 9;
    // config 初始化加载过一次后的，其实页码  后续把其移到单独的配置文件中
    private static final int PAGEINDEX = 2;

    @Scheduled(initialDelay = 1000, fixedDelay = 100*1000)
    public void process() {
        Spider spider = Spider.create(new JobProcessor())
                .addUrl(MessageFormat.format(url, "1"))
                // BloomFilterDuplicateRemover 如果使用布隆策略，51job的很多超链接会丢失
                /*.setScheduler(new QueueScheduler()
                        .setDuplicateRemover(
                                new BloomFilterDuplicateRemover(10*000)
                        ))*/
                .addPipeline(this.springDataPipeline)
                .thread(5);
        //.run();
        spider.run();
    }

    private Site site = Site.me()
            .setCharset("gbk") // utf8  当前51job的页面是jbk的编码
            //.setUserAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36")
            .setTimeOut(10*1000) // 超时
            .setRetrySleepTime(3*1000) // 重试的间隔时间
            .setRetryTimes(3); // 重试次数

    @Override
    public Site getSite() {
        return site;
    }
    @Override
    public void process(Page page) {

        // 因为数据在<script>标签里
        String dataJson = page.getHtml().xpath("//script").regex(".*engine_search_result.*").get();
        // System.out.println(dataJson);
        if(dataJson != null && dataJson.trim().length() > 0){
            // 去除json数据之外的 内容
            dataJson = dataJson.substring(dataJson.indexOf('{'));
            dataJson = dataJson.substring(0,dataJson.lastIndexOf('}')+1);
            // json表达式，获取源数据
            JsonPathSelector jsonPathSelector = new JsonPathSelector("$.engine_search_result[*].job_href");
            List<String> list = jsonPathSelector.selectList(dataJson);
            System.out.println(list.size());
            for (String jobInfoUrl : list) {
                // 抓取过http://hundsun.51job.com/show_job_detail.html?jobid=128172015
                if(jobInfoUrl.contains("jobs.51job.com"))
                    page.addTargetRequest(jobInfoUrl);
            }
            // 下一页
        }else{
            // 如果为空，表示这是招聘详情页，解析页面，获取招聘详情信息，保存数据
            this.saveJobInfo(page);
        }
        // 下一页 MessageFormat.format("http://www.{0}.com", "baidu")
        for (int i = PAGEINDEX; i < PAGESIZE; i++) {
            // System.out.println("翻页："+i);
            String nextPageUrl =  MessageFormat.format(url, i);
            page.addTargetRequest(nextPageUrl);
            // log.info("nextPageUrl:{}",nextPageUrl);
        }


        // 解析页面，获取招聘信息详情的url地址
       /* List<Selectable> nodes = page.getHtml().css("div.rjlist div.e").nodes();
        System.out.println(nodes.size());
        // 判断获取到的集合是否为空
        if(nodes.size()==0){
            // 如果为空，表示这是招聘详情页，解析页面，获取招聘详情信息，保存数据
            this.saveJobInfo(page);
        }else {
            // 如果不为空，表示这是列表页，解析出详情页的url地址，放到任务队列中
            for (Selectable node : nodes) {
                String jobInfoUrl = node.links().toString();
                System.out.println(jobInfoUrl);
                page.addTargetRequest(jobInfoUrl);
            }
            // 下一页
        }*/


    }
    // 解析页面，获取招聘详情信息，保存数据
    private void saveJobInfo(Page page) {
        // 创建招聘详情对象
        Html html = page.getHtml();
        JobInfo jobInfo = new JobInfo();
        // 解析页面
        // 地区和发布时间这个不好抓取 String str = "深圳-罗湖区    1年经验    本科    招3人    01-04发布    软件工程 计算机科学与技术";
        String ltypes = Jsoup.parse(html.css("p.ltype").toString()).text();
        ltypes = ltypes.replaceAll("&nbsp;", "").replaceAll("\\s*","").replaceAll(" ","");
        String[] arr = ltypes.split("\\|");
        for (int i = 0; i < arr.length; i++) {
            jobInfo.setJobAddr(arr[0]); // 第一个一般是地点
            if(arr[i].contains("发布")){
                jobInfo.setTime(arr[i].substring(0,arr[i].length()-2));
            }
        }
        jobInfo.setCompanyName(html.css("p.cname a","text").toString());
        jobInfo.setCompanyInfo(Jsoup.parse(html.css("div.tmsg").toString()).text());
        if(html.css("div.bmsg").nodes().size() > 1){
            jobInfo.setCompanyAddr(Jsoup.parse(html.css("div.bmsg").nodes().get(1).toString()).text());
        }
        jobInfo.setJobName(html.css("div.cn h1","text").toString());
        jobInfo.setJobInfo(Jsoup.parse(html.css("div.job_msg").toString()).text());
        jobInfo.setJobInfoHtml(html.css("div.job_msg").toString());
        // 薪资
        Integer[] salarys = MathSalary.getSalary(html.css("div.cn strong", "text").toString());
        System.out.println(salarys[0]);
        jobInfo.setSalaryMin(salarys[0]);
        jobInfo.setSalaryMax(salarys[1]);
        jobInfo.setSalary(html.css("div.cn strong", "text").toString());

        jobInfo.setUrl(page.getUrl().toString());
        // 保存数据
        page.putField("jobInfo",jobInfo);

    }


}
